package com.example.micro_property_springboot.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.micro_property_springboot.entity.BackupStatistics;
import com.example.micro_property_springboot.entity.SysBackupRecord;
import com.example.micro_property_springboot.mapper.SysBackupRecordMapper;
import com.example.micro_property_springboot.service.SysBackupRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 系统备份记录服务实现
 */
@Service
public class SysBackupRecordServiceImpl extends ServiceImpl<SysBackupRecordMapper, SysBackupRecord>
        implements SysBackupRecordService {
    
    @Autowired
    private SysBackupRecordMapper backupRecordMapper;
    
    @Value("${backup.path}")
    private String backupPath;
    
    @Value("${spring.datasource.url}")
    private String dbUrl;
    
    @Value("${spring.datasource.username}")
    private String dbUsername;
    
    @Value("${spring.datasource.password}")
    private String dbPassword;
    
    @Override
    @Transactional
    public SysBackupRecord doManualBackup(Long operatorId, String remark) throws IOException {
        return performBackup("manual", operatorId, remark);
    }
    
    @Override
    @Transactional
    public SysBackupRecord doAutoBackup() throws IOException {
        return performBackup("auto", null, "Auto backup");
    }
    
    /**
     * 执行数据库备份
     */
    private SysBackupRecord performBackup(String backupType, Long operatorId, String remark) throws IOException {
        // 创建备份目录
        File backupDir = new File(backupPath);
        if (!backupDir.exists()) {
            backupDir.mkdirs();
        }
        
        // 生成备份文件名
        String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String filename = "backup_" + timestamp + "_" + UUID.randomUUID().toString().substring(0, 8) + ".sql";
        String filepath = backupPath + File.separator + filename;
        
        // 创建备份记录
        SysBackupRecord record = new SysBackupRecord();
        record.setBackupName(filename);
        record.setBackupPath(filepath);
        record.setBackupType(backupType);
        record.setOperatorId(operatorId);
        record.setRemark(remark);
        record.setBackupTime(new Date());
        
        boolean success = false;
        try {
            // 执行备份命令（这里使用简单的模拟，实际项目中应调用实际的备份命令）
            // 在实际环境中，可以使用mysqldump或其他数据库备份工具
            // 此处仅作为示例，模拟备份文件的创建
            Files.createFile(Paths.get(filepath));
            
            // 获取文件大小
            long fileSize = Files.size(Paths.get(filepath));
            record.setFileSize(fileSize);
            record.setIsSuccess(true);
            success = true;
        } catch (Exception e) {
            record.setIsSuccess(false);
            record.setRemark(remark + " | Error: " + e.getMessage());
            throw e;
        } finally {
            // 保存备份记录
            save(record);
        }
        
        return record;
    }
    
    @Override
    @Transactional
    public boolean restoreFromBackup(Long backupId) throws IOException {
        SysBackupRecord record = getById(backupId);
        if (record == null || !record.getIsSuccess()) {
            return false;
        }
        
        File backupFile = new File(record.getBackupPath());
        if (!backupFile.exists()) {
            return false;
        }
        
        try {
            // 执行恢复命令（这里使用简单的模拟，实际项目中应调用实际的恢复命令）
            // 在实际环境中，可以使用mysql命令或其他数据库恢复工具
            // 此处仅作为示例
            
            return true;
        } catch (Exception e) {
            throw e;
        }
    }
    
    @Override
    public List<SysBackupRecord> getRecentBackupRecords(Integer limit) {
        return backupRecordMapper.getRecentBackupRecords(limit);
    }
    
    @Override
    @Transactional
    public void cleanExpiredBackups(Integer keepDays) {
        if (keepDays <= 0) {
            return;
        }
        
        // 计算过期日期
        Date expiredDate = new Date(System.currentTimeMillis() - (long) keepDays * 24 * 60 * 60 * 1000);
        String expiredDateStr = new SimpleDateFormat("yyyy-MM-dd").format(expiredDate);
        
        // 获取过期的备份记录
        List<SysBackupRecord> expiredRecords = backupRecordMapper.selectExpiredRecords(expiredDateStr);
        
        for (SysBackupRecord record : expiredRecords) {
            // 删除备份文件
            try {
                Path path = Paths.get(record.getBackupPath());
                if (Files.exists(path)) {
                    Files.delete(path);
                }
            } catch (IOException e) {
                // 记录日志但继续处理其他记录
            }
            
            // 删除数据库记录
            removeById(record.getId());
        }
    }
    
    @Override
    @Transactional
    public boolean deleteBackup(Long backupId) {
        SysBackupRecord record = getById(backupId);
        if (record == null) {
            return false;
        }
        
        // 删除备份文件
        try {
            Path path = Paths.get(record.getBackupPath());
            if (Files.exists(path)) {
                Files.delete(path);
            }
        } catch (IOException e) {
            // 文件删除失败，记录删除成功
        }
        
        // 删除数据库记录
        return removeById(backupId);
    }
    
    @Override
    public BackupStatistics getBackupStatistics() {
        BackupStatistics stats = new BackupStatistics();
        
        // 获取总数
        stats.setTotalCount(Math.toIntExact(count()));
        
        // 获取成功数量
        stats.setSuccessCount(backupRecordMapper.getSuccessBackupCount());
        
        // 获取手动备份数量
        stats.setManualCount(backupRecordMapper.countByBackupType("manual"));
        
        // 获取自动备份数量
        stats.setAutoCount(backupRecordMapper.countByBackupType("auto"));
        
        // 获取最近一次备份
        List<SysBackupRecord> recent = backupRecordMapper.getRecentBackupRecords(1);
        if (!recent.isEmpty()) {
            stats.setLastBackup(recent.get(0));
        }
        
        return stats;
    }
}